unit SystemInfoUtils;

interface

uses
  Windows, Classes, SysUtils, Registry, ShellAPI, Forms;

function GetSysCom(var AComListResult: TStrings): Boolean;

function WindowsDialogCopyFile(const AFrom, ATo: String;
  AMove: Boolean = False): Boolean;

procedure GetSysStoreDrivers(var ResultDrivers: TStrings;
  CDROM, REMOVABLE, FIXED, REMOTE, RAMDISK, NO_ROOT_DIR, UNKNOWN: Boolean);

function GetCPUID(): String;
function GetMacAddress: string;

implementation

function GetMacAddress: string;
var
  Lib: Cardinal;
  Func: function(GUID: PGUID): Longint; stdcall;
  GUID1, GUID2: TGUID;
begin
  Result := '';
  Lib := LoadLibrary('rpcrt4.dll');
  if Lib <> 0 then
  begin
    if Win32Platform <>VER_PLATFORM_WIN32_NT then
      @Func := GetProcAddress(Lib, 'UuidCreate')
      else @Func := GetProcAddress(Lib, 'UuidCreateSequential');
    if Assigned(Func) then
    begin
      if (Func(@GUID1) = 0) and
        (Func(@GUID2) = 0) and
        (GUID1.D4[2] = GUID2.D4[2]) and
        (GUID1.D4[3] = GUID2.D4[3]) and
        (GUID1.D4[4] = GUID2.D4[4]) and
        (GUID1.D4[5] = GUID2.D4[5]) and
        (GUID1.D4[6] = GUID2.D4[6]) and
        (GUID1.D4[7] = GUID2.D4[7]) then
      begin
        Result :=
         IntToHex(GUID1.D4[2], 2) + '-' +
         IntToHex(GUID1.D4[3], 2) + '-' +
         IntToHex(GUID1.D4[4], 2) + '-' +
         IntToHex(GUID1.D4[5], 2) + '-' +
         IntToHex(GUID1.D4[6], 2) + '-' +
         IntToHex(GUID1.D4[7], 2);
      end;
    end;
    FreeLibrary(Lib);
  end;
end;


function GetCPUID(): String;
var
  _eax, _ebx, _ecx, _edx: Longword;
  s, s1, s2: string;
begin
 asm
     push eax
     push ebx
     push ecx
     push edx
     mov eax,1
     db $0F,$A2
     mov _eax,eax
     mov _ebx,ebx
     mov _ecx,ecx
     mov _edx,edx
     pop edx
     pop ecx
     pop ebx
     pop eax
    end;
   s := IntToHex(_eax, 8);
   s1 := IntToHex(_edx, 8);
   s2 := IntToHex(_ecx, 8);
   Result:=s+s1+s2;
end;

procedure GetSysStoreDrivers(var ResultDrivers: TStrings;
  CDROM, REMOVABLE, FIXED, REMOTE, RAMDISK, NO_ROOT_DIR, UNKNOWN: Boolean);
var
  Drivers: Integer;
  Temp: Integer;
  I: Integer;
  Driver: Char;
  DriverName: string;
  DriverType: Integer;
begin
  Drivers := GetLogicalDrives();
  Temp := 1 and Drivers;
  for I := 0 to 26 do
  begin
    if Temp = 1 then
    begin
      Driver := Char(I + Integer('A'));
      if (Driver <> '') then
      begin
        DriverName := Driver + ':\';
        DriverType := GetDriveType(PChar(DriverName));
        if (CDROM or (DriverType <> DRIVE_CDROM)) and
          (REMOVABLE or (DriverType <> DRIVE_REMOVABLE)) and
          (FIXED or (DriverType <> DRIVE_FIXED)) and
          (REMOTE or (DriverType <> DRIVE_REMOTE)) and
          (RAMDISK or (DriverType <> DRIVE_RAMDISK)) and
          (NO_ROOT_DIR or (DriverType <> DRIVE_NO_ROOT_DIR)) and
          (UNKNOWN or (DriverType <> DRIVE_UNKNOWN)) then
        begin
          ResultDrivers.Add(DriverName);
        end;
      end;
    end;
    Drivers := (Drivers shr 1);
    Temp := (1 and Drivers);
  end;
end;

function WindowsDialogCopyFile(const AFrom, ATo: String;
  AMove: Boolean = False): Boolean;
var
  lpFileOp: TSHFileOpStruct;
begin
  FillChar(lpFileOp,SizeOf(TSHFileOpStruct),#0);
  with lpFileOp do
  begin
    Wnd := Application.Handle;
    if AMove then
      wFunc := FO_MOVE
    else
      wFunc := FO_COPY;
    pFrom := PChar(AFrom);
    pTo := PChar(ATo);
    fFlags := FOF_NOCONFIRMATION or FOF_SIMPLEPROGRESS;
    hNameMappings := nil;
    lpszProgressTitle := nil;
    fAnyOperationsAborted := False;
  end;
  Result := SHFileOperation(lpFileOp) = 0;

end;

function GetSysCom(var AComListResult: TStrings): Boolean;
var
  I: Integer;
  Reg: TRegistry;
  TmpList: TStrings;
begin
  Reg := TRegistry.Create;
  Reg.RootKey := HKEY_LOCAL_MACHINE;
  if Reg.OpenKey('hardware\devicemap\serialcomm', False) then
  begin
    TmpList := TStringList.Create;
    try
      Reg.GetValueNames(TmpList);
      for I := 0 to TmpList.Count - 1 do
      begin
        AComListResult.Add(Reg.ReadString(TmpList.Strings[I]));
      end;
    finally
      FreeAndNil(TmpList);
    end;
  end;
  FreeAndNil(Reg);
  if AComListResult.Count > 0 then
    Result := True
  else
    Result := False;
end;

end.
